package com.ruoyi.ring.service.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import com.alibaba.fastjson2.JSON;
import com.google.gson.Gson;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.SleepTypeEnums;
import com.ruoyi.common.enums.TimeUnitEnums;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.bean.Builder;
import com.ruoyi.ora.constant.BizConstants;
import com.ruoyi.ring.domain.*;
import com.ruoyi.ring.domain.dto.RingSleepDetailInfoDTO;
import com.ruoyi.ring.domain.dto.RingSleepDetailListDTO;
import com.ruoyi.ring.domain.dto.SleepInfoDTO;
import com.ruoyi.ring.domain.dto.VerifyQueryDTO;
import com.ruoyi.ring.domain.vo.*;
import com.ruoyi.ring.factory.AiFactory;
import com.ruoyi.ring.mapper.*;
import com.ruoyi.ring.service.IRingSleepDetailService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * 睡眠详情Service业务层处理
 * 
 * @author liuwp
 * @date 2025-08-18
 */
@Slf4j
@Service
public class RingSleepDetailServiceImpl implements IRingSleepDetailService 
{
    @Resource
    private RingSleepDetailMapper ringSleepDetailMapper;
    @Resource
    private RingSleepInfoMapper ringSleepInfoMapper;
    @Resource
    private RingSleepTypeMapper ringSleepTypeMapper;
    @Resource
    private RingHeartRateInfoMapper ringHeartRateInfoMapper;
    @Resource
    private RingHrvInfoMapper ringHrvInfoMapper;
    @Resource
    private RingEventInfoMapper ringEventInfoMapper;
    @Resource
    private RingBloodOxygenMapper ringBloodOxygenMapper;

    /**
     * 查询睡眠详情
     * 
     * @param id 睡眠详情主键
     * @return 睡眠详情
     */
    @Override
    public RingSleepDetail selectRingSleepDetailById(Long id)
    {
        return ringSleepDetailMapper.selectRingSleepDetailById(id);
    }

    @Override
    public List<Integer> verify(VerifyQueryDTO queryDTO) {
        String deviceSn = queryDTO.getDeviceSn();
        List<Long> dateList = queryDTO.getDateList();
        List<Integer> resultList = new ArrayList<>();
        for(int i =0; i < dateList.size(); i++){
            Long date = dateList.get(i);
            if(date != 0){
                String strDate = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS,new Date(date));
                log.info("deviceSn:{}, strDate:{}",deviceSn,strDate);
                Date startDate = DateUtils.dateTime(DateUtils.YYYY_MM_DD_HH_MM_SS,strDate);
                RingSleepDetail sleepDetail = ringSleepDetailMapper.selectOneRingSleepDetail(Builder.of(RingSleepDetail::new).
                        with(RingSleepDetail::setDeviceSn,deviceSn).
                        with(RingSleepDetail::setStartDate,startDate).build());
                if(sleepDetail == null){
                    resultList.add(i);
                }
            }
        }
        log.info("resultList:{}",JSON.toJSONString(resultList));
        return resultList;
    }

    /**
     * 查询睡眠详情列表
     * 
     * @param ringSleepDetail 睡眠详情
     * @return 睡眠详情
     */
    @Override
    public List<RingSleepDetail> selectRingSleepDetailList(RingSleepDetail ringSleepDetail)
    {
        return ringSleepDetailMapper.selectRingSleepDetailList(ringSleepDetail);
    }

    /**
     * 根据业务主键查询一条记录：睡眠详情
     *
     * @param ringSleepDetail 睡眠详情
     * @return 睡眠详情
     */
    @Override
    public RingSleepDetail selectOneRingSleepDetail(RingSleepDetail ringSleepDetail)
    {
        return ringSleepDetailMapper.selectOneRingSleepDetail(ringSleepDetail);
    }

    /**
     * 新增睡眠详情
     * 
     * @param ringSleepDetail 睡眠详情
     * @return 结果
     */
    @Override
    public int insertRingSleepDetail(RingSleepDetail ringSleepDetail)
    {
        ringSleepDetail.setCreateTime(DateUtils.getNowDate());
        return ringSleepDetailMapper.insertRingSleepDetail(ringSleepDetail);
    }

    /**
     * 修改睡眠详情
     * 
     * @param ringSleepDetail 睡眠详情
     * @return 结果
     */
    @Override
    public int updateRingSleepDetail(RingSleepDetail ringSleepDetail)
    {
        ringSleepDetail.setUpdateTime(DateUtils.getNowDate());
        return ringSleepDetailMapper.updateRingSleepDetail(ringSleepDetail);
    }

    @Override
    public int updateRingSleepDetailCondition(RingSleepDetail ringSleepDetail, RingSleepDetail ringSleepDetailCondition)
    {
                ringSleepDetail.setUpdateTime(DateUtils.getNowDate());
        return ringSleepDetailMapper.updateRingSleepDetailCondition(ringSleepDetail, ringSleepDetailCondition);
    }

    /**
     * 批量删除睡眠详情
     * 
     * @param ids 需要删除的睡眠详情主键
     * @return 结果
     */
    @Override
    public int deleteRingSleepDetailByIds(Long[] ids)
    {
        return ringSleepDetailMapper.deleteRingSleepDetailByIds(ids);
    }

    /**
     * 删除睡眠详情信息
     * 
     * @param id 睡眠详情主键
     * @return 结果
     */
    @Override
    public int deleteRingSleepDetailById(Long id)
    {
        return ringSleepDetailMapper.deleteRingSleepDetailById(id);
    }

    /**
     * 条件删除睡眠详情
     *
     * @param ringSleepDetail 睡眠详情
     * @return 结果
     */
    @Override
    public int deleteRingSleepDetailByCondition(RingSleepDetail ringSleepDetail)
    {
        return ringSleepDetailMapper.deleteRingSleepDetailByCondition(ringSleepDetail);
    }

    @Override
    public List<RingSleepDetail> queryList(RingSleepDetailListDTO sleepDetailListDTO) {
        return ringSleepDetailMapper.queryList(sleepDetailListDTO);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public int addDetail(SleepInfoDTO sleepInfo) {
        RingSleepDetail ringSleepDetail = ringSleepDetailMapper.selectOneRingSleepDetail(Builder.of(RingSleepDetail::new).
                with(RingSleepDetail::setDeviceSn, sleepInfo.getDeviceSn()).
                with(RingSleepDetail::setStartDate, sleepInfo.getStartDate()).
                with(RingSleepDetail::setEndDate, sleepInfo.getEndDate()).build());
        if(ringSleepDetail == null){
            try {
                RingSleepDetail  sleepDetail = Convert.convert(RingSleepDetail.class, sleepInfo);
                sleepDetail.setCreateTime(DateUtils.getNowDate());
                int[] result = sleepInfo.getRawBytes();
                if(result.length >0){
                    String rawBytes = IntStream.of(result).mapToObj(String::valueOf).collect(Collectors.joining(", "));
                    sleepDetail.setRawBytes(rawBytes);
                }
                List<RingSleepInfo> sleepInfos = Convert.toList(RingSleepInfo.class,sleepInfo.getDetails());
                ringSleepDetailMapper.addRingSleepDetail(sleepDetail);
                Long id = sleepDetail.getId();
                sleepInfos.forEach(s -> {
                    s.setRingSleepId(id);
                    s.setCreateTime(DateUtils.getNowDate());
                });
                if(sleepInfos.size() > 0){
                    ringSleepInfoMapper.insertRingSleepInfos(sleepInfos);
                }
                RingSleepType sleepType = Convert.convert(RingSleepType.class,sleepDetail);
                sleepType.setId(null);
                sleepType.setRingSleepId(id);
                ringSleepTypeMapper.insertRingSleepType(sleepType);
                return id.intValue();
            }catch (Exception e){
                throw new RuntimeException("插入数据失败！"+ e.getMessage());
            }
        }else {
            throw new RuntimeException("");
        }
    }

    @Override
    public List<CalendarResultVO> queryCalendarList(RingSleepDetailInfoDTO sleepDetailInfoDTO) {
        List<RingSleepDetail> sleepDetails = ringSleepDetailMapper.selectRingSleepDetailList(Builder.of(RingSleepDetail::new).with(RingSleepDetail::setDeviceSn, sleepDetailInfoDTO.getDeviceSn()).build());
        List<CalendarResultVO> resultVOS = Convert.toList(CalendarResultVO.class,sleepDetails);
        ZoneId zoneId = ZoneId.systemDefault();
        List<CalendarResultVO> list = resultVOS.stream()
                .collect(Collectors.toMap(
                        vo -> vo.getDailyValue().toInstant().atZone(zoneId).toLocalDate(),
                        Function.identity(),
                        (existing, replacement) -> existing
                ))
                .values()
                .stream()
                // 使用Comparator.comparing指定按日期正序
                .sorted(Comparator.comparing(vo -> vo.getDailyValue().toInstant().atZone(zoneId).toLocalDate()))
                .collect(Collectors.toList());
         return list;
    }

    @Override
    public RingSleepDetailVO queryDayInfo(RingSleepDetailInfoDTO sleepDetailInfoDTO) {
        RingSleepDetailVO sleepDetailVO = new RingSleepDetailVO();
        RingSleepDetailVO longSleepInfo = ringSleepDetailMapper.queryLongSleepInfo(sleepDetailInfoDTO);
        int longSleepTime = 0; //长睡眠时长
        int shortSleepTime = 0;//短睡眠时长
        if (longSleepInfo != null){
            sleepDetailVO = Convert.convert(RingSleepDetailVO.class,longSleepInfo);
            longSleepTime = longSleepInfo.getTotalTime();
            Date startDate = longSleepInfo.getStartDate();//长睡眠开始时间
            // 将Date转换为LocalDateTime（需指定时区，这里用系统默认时区）
            LocalDateTime localDateTime = startDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
            // 获取分钟（0-59）
            int minute = localDateTime.getMinute();
            List<RingSleepInfoVO> list = new ArrayList<>();
            List<RingSleepInfo> ringSleepInfoList =  ringSleepInfoMapper.selectRingSleepInfoList(Builder.of(RingSleepInfo::new).with(RingSleepInfo::setRingSleepId, longSleepInfo.getId()).build());
            ringSleepInfoList.stream().sorted(Comparator.comparing(RingSleepInfo::getId)).collect(Collectors.toList()).forEach(r ->{
                RingSleepInfoVO infoVO = new RingSleepInfoVO();
                infoVO.setStartTime(DateUtils.calculateTimeAfterMinutes(startDate,r.getStartTime()-minute));
                infoVO.setEndTime(DateUtils.calculateTimeAfterMinutes(startDate,r.getEndTime()-minute));
                infoVO.setTotalTime(r.getTotalTime());
                infoVO.setSleepType(r.getSleepType());
                list.add(infoVO);
            });
            Map<Integer, List<RingSleepInfoVO>> groupedMap = list.stream().collect(Collectors.groupingBy(RingSleepInfoVO::getSleepType));
            sleepDetailVO.setMaps(groupedMap);
            sleepDetailVO.setLongSleepDuration(DateUtils.convertMinutesToChinese(longSleepTime));
        }
        List<RingSleepDetailVO> shortSleepInfoList = ringSleepDetailMapper.queryShortSleepInfo(sleepDetailInfoDTO);
        if(shortSleepInfoList.size() > 0){
            RingSleepDetailVO shortSleepInfo = shortSleepInfoList.get(0);
            Date startTime = shortSleepInfo.getStartDate();
            Date endTime = shortSleepInfo.getEndDate();
            shortSleepTime = Convert.toInt(DateUtils.getMinutesBetweenDates(startTime, endTime));
            sleepDetailVO.setShortSleepDuration(DateUtils.convertMinutesToChinese(shortSleepTime));
            sleepDetailVO.setShortSleepStartTime(DateUtils.convertDateTimeToHHMM(startTime));
            sleepDetailVO.setShortSleepEndTime(DateUtils.convertDateTimeToHHMM(endTime));
        }else {
            sleepDetailVO.setShortSleepDuration("--");
            sleepDetailVO.setShortSleepStartTime("--");
            sleepDetailVO.setShortSleepEndTime("--");
        }
        sleepDetailVO.setSleepDuration(DateUtils.convertMinutesToChinese(longSleepTime+shortSleepTime));
        return sleepDetailVO;
    }

    @Override
    public WeekOrMonthInfoVO queryWeekOrMonthInfo(RingSleepDetailInfoDTO sleepDetailInfoDTO) {
        WeekOrMonthInfoVO weekOrMonthInfoVO = new WeekOrMonthInfoVO();
        List<RingSleepDetail> longSleepDetails = ringSleepDetailMapper.queryWeekOrMonthLongInfo(sleepDetailInfoDTO);
        List<RingSleepDetail> shortSleepDetails = ringSleepDetailMapper.queryWeekOrMonthShortInfo(sleepDetailInfoDTO);
        if(longSleepDetails != null || shortSleepDetails != null){
            long longCount = longSleepDetails.stream().count();//长睡眠数量
            long longTotalSum = longSleepDetails.stream().mapToLong(l -> l.getTotalTime()).sum();// 长睡眠总时长

            long shortCount = shortSleepDetails.stream().count();//短睡眠数量
            AtomicLong shortTimes = new AtomicLong(0L);
            shortSleepDetails.forEach(shortSleep ->{
                long result = DateUtils.getMinutesBetweenDates(shortSleep.getStartDate(),shortSleep.getEndDate());
                shortTimes.set(result);
            });
            long shortTotalSum = shortTimes.get();// 短睡眠总时长

            long longSum = longCount == 0L ? 0L : longTotalSum/longCount;
            long shortSum = shortCount == 0L ? 0L : shortTotalSum/shortCount;
            long totalSum = (longCount + shortCount) == 0L ? 0L : (longTotalSum + shortTotalSum) / (longCount + shortCount);

            weekOrMonthInfoVO.setAverage(DateUtils.convertMinutesToChinese((int)(totalSum)));
            weekOrMonthInfoVO.setLongAverage(DateUtils.convertMinutesToChinese((int)(longSum)));
            weekOrMonthInfoVO.setShortAverage(DateUtils.convertMinutesToChinese((int)(shortSum)));
            Date dateStart = TimeUnitEnums.WEEK.getCode().equals(sleepDetailInfoDTO.getType()) ? DateUtils.getWeekStart(sleepDetailInfoDTO.getDailyValue(), ZoneId.systemDefault()) : DateUtils.getMonthStart(sleepDetailInfoDTO.getDailyValue(), ZoneId.systemDefault());
            Date dateEnd = TimeUnitEnums.WEEK.getCode().equals(sleepDetailInfoDTO.getType()) ? DateUtils.getWeekEnd(sleepDetailInfoDTO.getDailyValue(), ZoneId.systemDefault()) : DateUtils.getMonthEnd(sleepDetailInfoDTO.getDailyValue(), ZoneId.systemDefault());
            weekOrMonthInfoVO.setDateStart(DateUtils.dateTimeChinese(dateStart) + "，" + DateUtils.queryWeekday(dateStart));
            weekOrMonthInfoVO.setDateEnd(DateUtils.dateTimeChinese(dateEnd) + "，" + DateUtils.queryWeekday(dateEnd));
            List<RingWeekOrMonthSleepVO> ringWeekOrMonthSleepVOS = new ArrayList<>();
            longSleepDetails.forEach(s ->{
                RingWeekOrMonthSleepVO ringWeekOrMonthSleepVO = new RingWeekOrMonthSleepVO();
                if("2".equals(sleepDetailInfoDTO.getType())) ringWeekOrMonthSleepVO.setDailyValue(DateUtils.convertDateToMMdd(s.getDailyValue()));
                if("3".equals(sleepDetailInfoDTO.getType())) ringWeekOrMonthSleepVO.setDailyValue(DateUtils.queryMonthday(s.getDailyValue()));
                List<RingWeekOrMonthSleepVO.RingWeekOrMonthSleep> list = new ArrayList<>();
                RingWeekOrMonthSleepVO.RingWeekOrMonthSleep weekOrMonthSleep = new RingWeekOrMonthSleepVO.RingWeekOrMonthSleep();
                weekOrMonthSleep.setValue(s.getAwakeTime());
                list.add(weekOrMonthSleep);
                weekOrMonthSleep = new RingWeekOrMonthSleepVO.RingWeekOrMonthSleep();
                weekOrMonthSleep.setValue(s.getRemTime());
                list.add(weekOrMonthSleep);
                weekOrMonthSleep = new RingWeekOrMonthSleepVO.RingWeekOrMonthSleep();
                weekOrMonthSleep.setValue(s.getLightTime());
                list.add(weekOrMonthSleep);
                weekOrMonthSleep = new RingWeekOrMonthSleepVO.RingWeekOrMonthSleep();
                weekOrMonthSleep.setValue(s.getDeepTime());
                list.add(weekOrMonthSleep);
                ringWeekOrMonthSleepVO.setWeekOrMonthSleeps(list);
                ringWeekOrMonthSleepVOS.add(ringWeekOrMonthSleepVO);
            });
            weekOrMonthInfoVO.setRingWeekOrMonthSleepVOS(ringWeekOrMonthSleepVOS);
        }
        return weekOrMonthInfoVO;
    }

    /**
     * 当今⽇睡眠时⻓⼩于等于300分钟时： 睡眠质量评分 = 睡眠时⻓ / 5；
     * 今⽇睡眠时⻓⼤于300分钟时：
     * 睡眠质量评分 = 100 - 扣分 * 3
     * @param sleepDetailInfoDTO
     * @return
     */
    @Override
    public RingSleepQualityScoreVO queryQualityScore(RingSleepDetailInfoDTO sleepDetailInfoDTO) {
        RingSleepQualityScoreVO qualityScoreVO = new RingSleepQualityScoreVO();
        int score = 0;//总得分
        String bedRestTime = "";//卧床时间
        int sleepEfficiency = 0;//睡眠效率
        int sleepLatency = 0;//睡眠潜伏期
        String evaluation = "";//时机
        String summary = "无";//ai总结
        List<RingSleepDetail> sleepRegularityList = ringSleepDetailMapper.querySleepRegularityList(sleepDetailInfoDTO);
        //睡眠规律醒（最近7天）
        int sleepTotalCount = sleepRegularityList.size();
        if(sleepTotalCount > 0){

            //查询当天睡眠信息
            List<RingSleepDetail> sleepDurations = ringSleepDetailMapper.selectRingSleepDetailList(Builder.of(RingSleepDetail::new).
                    with(RingSleepDetail::setDeviceSn, sleepDetailInfoDTO.getDeviceSn()).
                    with(RingSleepDetail::setDailyValue, sleepDetailInfoDTO.getDailyValue()).
                    with(RingSleepDetail::setSleepType, SleepTypeEnums.LONG_SLEEP.getCode())
                    .build()).stream().sorted(Comparator.comparing(RingSleepDetail::getId)).collect(Collectors.toList());
            //取出当天睡眠时间最长的
            RingSleepDetail ringSleepDetail = sleepDurations.stream().max(Comparator.comparingInt(RingSleepDetail::getTotalTime)).orElse(null);

            log.info("--ringSleepDetail-- deviceSn：{} ， :{}", sleepDetailInfoDTO.getDeviceSn(), JSON.toJSONString(ringSleepDetail));
            if(ringSleepDetail != null){
                bedRestTime = DateUtils.convertMinutesToChinese(ringSleepDetail.getTotalTime()+ringSleepDetail.getAwakeTime());//卧床时间
                sleepEfficiency =sleepEfficiency(ringSleepDetail);//睡眠效率
                //获取最长一次睡眠的详情
                List<RingSleepInfo> ringSleepInfos =  ringSleepInfoMapper.selectRingSleepInfoList(Builder.of(RingSleepInfo::new).
                        with(RingSleepInfo::setRingSleepId, ringSleepDetail.getId()).build());
                List<RingSleepInfo> ringSleepInfoList = null;
                if(ringSleepInfos.size() > 0){
                    ringSleepInfoList = ringSleepInfos.stream().sorted(Comparator.comparing(RingSleepInfo::getStartTime)).collect(Collectors.toList());
                    //获取睡眠潜伏期
                    for (int i = 0; i < ringSleepInfoList.size() ; i++){
                        RingSleepInfo ringSleepInfo = ringSleepInfoList.get(i);
                        if(ringSleepInfo.getSleepType() == 0){
                            sleepLatency = ringSleepInfo.getTotalTime();
                            break;
                        }else {
                            continue;
                        }
                    }
                }
                // 计算中点时间   获取睡觉时机
                //时机（睡眠中点）：睡眠时间的中点落在0-3点之间：非常好  （optimal） 睡眠中点时间落在11-0，3-4点间，（前后差1小时）：good 良好   中点落在其他时间：差 （poor）
                long startTime = ringSleepDetail.getStartDate().getTime();
                long endTime = ringSleepDetail.getEndDate().getTime();
                long middleTime = startTime + (endTime - startTime) / 2;
                Date middleDate = new Date(middleTime);
                // 获取中点小时数
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(middleDate);
                int hour = calendar.get(Calendar.HOUR_OF_DAY); // 24小时制
                // 评估睡眠质量
                if (hour >= 0 && hour < 3) {
                    evaluation = "非常好";
                } else if ((hour >= 23 && hour <= 24) || (hour >= 3 && hour < 4)) {
                    evaluation = "良好";
                } else {
                    evaluation = "差";
                }

                if(ringSleepDetail.getTotalTime() <= 300){
                    score = ringSleepDetail.getTotalTime()/5;
                }else {
                    int deppSleepproportion = ringSleepDetail.getDeepTime()/ringSleepDetail.getTotalTime();//深睡眠比例
                    int proportionScore = 0;
                    if(deppSleepproportion < 10){
                        proportionScore = 3;
                    }else if(deppSleepproportion >= 10){
                        proportionScore = 2;
                    }else if(deppSleepproportion >= 15){
                        proportionScore = 1;
                    }else if(deppSleepproportion >= 20){
                        proportionScore = 0;
                    }
                    score+=proportionScore;
                    int regularScore = 0;//睡眠规律评分
                    if(sleepTotalCount < 3){
                        regularScore = 3;
                    }else if(sleepTotalCount >= 3){
                        regularScore = 2;
                    }else if(sleepTotalCount >= 5){
                        regularScore = 1;
                    }else if(sleepTotalCount >= 7){
                        regularScore = 0;
                    }
                    score+=regularScore;
                    //睡眠时长
                    int sleepTotalSum = sleepDurations.stream().mapToInt(s -> s.getTotalTime()).sum();// 求和
                    int sleepDurationScore = 0;
                    if(sleepTotalSum < 5*60){
                        sleepDurationScore = 3;
                    }else if(sleepTotalSum >= 5*60){
                        sleepDurationScore = 2;
                    }else if(sleepTotalSum >= 6*60){
                        sleepDurationScore = 1;
                    }else if(sleepTotalSum >= 7*60){
                        sleepDurationScore = 0;
                    }
                    score+=sleepDurationScore;
                    //清醒次数
                    long sleepTypeCount = ringSleepInfoList.size() > 0 ? ringSleepInfoList.stream().filter(rate -> rate.getSleepType() == 0).count() : 0;// 求总数
                    int sleepTypeScore = 0;
                    if(sleepTypeCount > 3){
                        sleepTypeScore = 3;
                    }else if(sleepTypeCount <= 3){
                        sleepTypeScore = 2;
                    }else if(sleepTypeCount <= 2){
                        sleepTypeScore = 1;
                    }else if(sleepTypeCount <= 1){
                        sleepTypeScore = 0;
                    }
                    score+=sleepTypeScore;

                    //清醒时长
                    int awakeTime = ringSleepDetail.getAwakeTime();
                    int awakeScore = 0;
                    if(awakeTime > 15){
                        awakeScore = 3;
                    }else if(awakeTime <= 15){
                        awakeScore = 2;
                    }else if(awakeTime <= 10){
                        awakeScore = 1;
                    }else if(awakeTime <= 5){
                        awakeScore = 0;
                    }
                    score+=awakeScore;
                    //入睡时间
                    calendar = Calendar.getInstance();
                    calendar.setTime(ringSleepDetail.getStartDate());
                    int hourNumber = calendar.get(Calendar.HOUR_OF_DAY); // 24小时制
                    int fallAsleepScore = 0;
                    if(hourNumber <= 23){
                        fallAsleepScore = 0;
                    }else if(7 > hourNumber && hourNumber > 1){
                        fallAsleepScore = 3;
                    }else if(hourNumber <= 1){
                        fallAsleepScore = 2;
                    }else if(hourNumber <= 0){
                        fallAsleepScore = 1;
                    }
                    score+=fallAsleepScore;
                    score = 100 - score*3;
                }
            }
        }

        if(score > 0){
            String aiContent = "通过睡眠质量评分："+score+ "分，对睡眠进行总结，描述的尽量详细并且50字以内描述，例如{\"summary\":\"xxx\"}，不要其他任何内容";
            String jsonStr = AiFactory.build(BizConstants.AI_PLATFORM.getValue()).chatCompletions(aiContent);
            Gson gson = new Gson();
            Map<String, Object> resultMap = gson.fromJson(jsonStr, Map.class);
            summary = resultMap.get("summary").toString();
        }
        // 100-85分:优秀 84-70分:良好 69-60分:合格 60分以下:不足
        String sleepValue = "--";
        if(score < 60){
            sleepValue = "不足";
        }
        if(score > 59 && score < 70 ){
            sleepValue = "合格";
        }
        if(score > 69 && score < 85 ){
            sleepValue = "良好";
        }
        if(score > 84 ){
            sleepValue = "优秀";
        }
        qualityScoreVO.setSleepValue(sleepValue);
        qualityScoreVO.setSleepScore(score);
        qualityScoreVO.setSleepDuration(bedRestTime);
        qualityScoreVO.setSleepEfficiency(sleepEfficiency);
        qualityScoreVO.setSleepLatency(sleepLatency);
        qualityScoreVO.setTiming(evaluation);
        qualityScoreVO.setSummary(summary);
        return qualityScoreVO;
    }
    /**
     * 睡眠效率
     * @param sleepDetail
     * @return
     */
    public static Integer sleepEfficiency(RingSleepDetail sleepDetail) {
        int sleepTime = sleepDetail.getTotalTime();//睡眠时间
        int bedriddenTime = sleepDetail.getAwakeTime() + sleepTime;//卧床时间
        // 避免除以零的情况
        if (bedriddenTime <= 0) {
            return 0;
        }
        double efficiency = Convert.toDouble(sleepTime) / Convert.toDouble(bedriddenTime) * 100;
        int result =  Convert.toInt(Math.round(efficiency));
        return result;
    }

    /**
     * 0：清醒 (Awake)
     * 1：浅睡眠 (Light Sleep)
     * 2：深睡眠 (Deep Sleep)
     * 3：REM睡眠 (快速眼动期)
     */
    @Override
    public Map<Integer, RingSleepProportionVO> queryProportion(RingSleepDetailInfoDTO sleepDetailInfoDTO) {
        Map<Integer, RingSleepProportionVO> map = new HashMap<>();
        List<RingSleepDetail>  sleepDetailList = ringSleepDetailMapper.querySleepInfo(sleepDetailInfoDTO);
        int longSleepTime = 0;
        int sleepType0 = 0;// 清醒 (Awake)
        int sleepType1 = 0;// 浅睡眠 (Light Sleep)
        int sleepType2 = 0;// 深睡眠 (Deep Sleep)
        int sleepType3 = 0;// REM睡眠 (快速眼动期)
        if(sleepDetailList.size() > 0){
            for(RingSleepDetail sleepDetail : sleepDetailList){
                longSleepTime += sleepDetail.getTotalTime();
                List<RingSleepInfo> ringSleepInfoList =  ringSleepInfoMapper.selectRingSleepInfoList(Builder.of(RingSleepInfo::new).with(RingSleepInfo::setRingSleepId, sleepDetail.getId()).build());
                Map<Integer, Integer> sumMap = ringSleepInfoList.stream()
                        .collect(Collectors.groupingBy(
                                RingSleepInfo::getSleepType,  // 分组依据
                                Collectors.summingInt(RingSleepInfo::getTotalTime)  // 计算每组的总和
                        ));
                if(sumMap.get(0) != null){
                    sleepType0 += sumMap.get(0);
                }
                if(sumMap.get(1) != null){
                    sleepType1 += sumMap.get(1);
                }
                if(sumMap.get(2) != null){
                    sleepType2 += sumMap.get(2);
                }
                if(sumMap.get(3) != null){
                    sleepType3 += sumMap.get(3);
                }
            }
            RingSleepProportionVO proportionVO = new RingSleepProportionVO();
            if(sleepType2 > 0){
                proportionVO = new RingSleepProportionVO();
                int result = NumberUtil.round(((double) sleepType2/longSleepTime)* 100, 0).intValue();
                if(result < 15) proportionVO.setRateValue("偏少");
                if(result >= 15 && result <= 25) proportionVO.setRateValue("适中");
                if(result > 25) proportionVO.setRateValue("偏多");
                proportionVO.setProportion(result);
                proportionVO.setSleepDuration(DateUtils.convertMinutesToChinese(sleepType2));
                map.put(2,proportionVO);
            }
            if(sleepType1 > 0){
                proportionVO = new RingSleepProportionVO();
                int result = NumberUtil.round(((double) sleepType1/longSleepTime)* 100, 0).intValue();
                if(result < 50) proportionVO.setRateValue("偏少");
                if(result >= 50 && result <= 60) proportionVO.setRateValue("适中");
                if(result > 60) proportionVO.setRateValue("偏多");
                proportionVO.setProportion(result);
                proportionVO.setSleepDuration(DateUtils.convertMinutesToChinese(sleepType1));
                map.put(1,proportionVO);
            }
            if(sleepType3 > 0){
                proportionVO = new RingSleepProportionVO();
                int result = NumberUtil.round(((double) sleepType3/longSleepTime)* 100, 0).intValue();
                if(result < 20) proportionVO.setRateValue("偏少");
                if(result >= 20 && result <= 25) proportionVO.setRateValue("适中");
                if(result > 25) proportionVO.setRateValue("偏多");
                proportionVO.setProportion(result);
                proportionVO.setSleepDuration(DateUtils.convertMinutesToChinese(sleepType3));
                map.put(3,proportionVO);
            }
            if(sleepType0 > 0){
                proportionVO = new RingSleepProportionVO();
                int result = NumberUtil.round(((double) sleepType0/longSleepTime)* 100, 0).intValue();
                if(result < 3) proportionVO.setRateValue("偏少");
                if(result >= 3 && result <= 5) proportionVO.setRateValue("适中");
                if(result > 5) proportionVO.setRateValue("偏多");
                proportionVO.setProportion(result);
                proportionVO.setSleepDuration(DateUtils.convertMinutesToChinese(sleepType0));
                map.put(0,proportionVO);
            }
        }
        return map;
    }

    @Override
    public AjaxResult queryShortSleep(RingSleepDetailInfoDTO sleepDetailInfoDTO) {
        RingShortSleepVO shortSleepVO = new RingShortSleepVO();
        List<RingSleepDetailVO>  shortSleepInfoList = ringSleepDetailMapper.queryShortSleepInfo(sleepDetailInfoDTO);
        if(shortSleepInfoList.size() > 0) {
            int totalTime = 0;
            if (TimeUnitEnums.DAY.getCode().equals(sleepDetailInfoDTO.getType())) {
                List<RingShortSleepVO.ShortSleepDate> shortSleepDates = new ArrayList<>();
                RingShortSleepVO.ShortSleepDate shortSleepDate = new RingShortSleepVO.ShortSleepDate();
                List<RingShortSleepVO.ShortSleepDate.ShortSleepTime> shortSleepTimes = new ArrayList<>();
                for (RingSleepDetailVO shortSleepInfo : shortSleepInfoList) {
                    RingShortSleepVO.ShortSleepDate.ShortSleepTime shortSleepTime = new RingShortSleepVO.ShortSleepDate.ShortSleepTime();
                    Date startTime = shortSleepInfo.getStartDate();
                    Date endTime = shortSleepInfo.getEndDate();
                    shortSleepTime.setStartDate(DateUtils.calculateTimeAfterMinutes(startTime, 0));
                    shortSleepTime.setEndDate(DateUtils.calculateTimeAfterMinutes(endTime, 0));
                    shortSleepTimes.add(shortSleepTime);
                    totalTime += Convert.toInt(DateUtils.getMinutesBetweenDates(startTime, endTime));
                }
                shortSleepDate.setShortSleepTimes(shortSleepTimes);
                shortSleepDate.setDailyValue(DateUtils.dateTime(sleepDetailInfoDTO.getDailyValue()));
                shortSleepDates.add(shortSleepDate);
                shortSleepVO.setSleepDuration(DateUtils.convertMinutesToChinese(totalTime));
                shortSleepVO.setShortSleepDates(shortSleepDates);
            } else {
                List<Date> days = new ArrayList<>();
                if (TimeUnitEnums.WEEK.getCode().equals(sleepDetailInfoDTO.getType()))
                    days = DateUtils.getWeekDatesLegacy(sleepDetailInfoDTO.getDailyValue());
                if (TimeUnitEnums.MONTH.getCode().equals(sleepDetailInfoDTO.getType()))
                    days = DateUtils.getMonthDatesLegacy(sleepDetailInfoDTO.getDailyValue());
                Map<Object, List<RingSleepDetailVO>> groupedByDailyValue = shortSleepInfoList.stream().collect(Collectors.groupingBy(RingSleepDetailVO::getDailyValue));
                int num = 0;
                List<RingShortSleepVO.ShortSleepDate> shortSleepDates = new ArrayList<>();
                for (Date date : days) {
                    String str = "--";
                    if (TimeUnitEnums.WEEK.getCode().equals(sleepDetailInfoDTO.getType()))
                        str = DateUtils.convertDateToMMdd(date);
                    if (TimeUnitEnums.MONTH.getCode().equals(sleepDetailInfoDTO.getType()))
                        str = DateUtils.queryMonthday(date);
                    List<RingShortSleepVO.ShortSleepDate.ShortSleepTime> shortSleepTimes = new ArrayList<>();
                    RingShortSleepVO.ShortSleepDate shortSleepDate = new RingShortSleepVO.ShortSleepDate();
                    Date convertDate = DateUtils.dateTime(DateUtils.YYYY_MM_DD, DateUtils.dateTime(date));
                    List<RingSleepDetailVO> list = groupedByDailyValue.get(convertDate);
                    if (list != null && list.size() > 0) {
                        for (RingSleepDetailVO shortSleepInfo : list) {
                            RingShortSleepVO.ShortSleepDate.ShortSleepTime shortSleepTime = new RingShortSleepVO.ShortSleepDate.ShortSleepTime();
                            Date startTime = shortSleepInfo.getStartDate();
                            Date endTime = shortSleepInfo.getEndDate();
                            shortSleepTime.setStartDate(DateUtils.calculateTimeAfterMinutes(startTime, 0));
                            shortSleepTime.setEndDate(DateUtils.calculateTimeAfterMinutes(endTime, 0));
                            shortSleepTimes.add(shortSleepTime);
                            totalTime += Convert.toInt(DateUtils.getMinutesBetweenDates(startTime, endTime));
                            num++;
                        }
                        shortSleepDate.setShortSleepTimes(shortSleepTimes);
                    }
                    shortSleepDate.setDailyValue(str);
                    shortSleepDates.add(shortSleepDate);
                    shortSleepVO.setShortSleepDates(shortSleepDates);
                    shortSleepVO.setSleepDuration(DateUtils.convertMinutesToChinese(num != 0 ? totalTime / num : 0));
                }
            }
        }
        return AjaxResult.success(shortSleepVO);
    }
    @Override
    public SleepHomeRateVO queryLongSleepHeartRate(RingSleepDetailInfoDTO sleepDetailInfoDTO) {
        if(TimeUnitEnums.DAY.getCode().equals(sleepDetailInfoDTO.getType())){
            SleepHomeRateVO sleepHomeRateVO = querySleepHeartRateResult(sleepDetailInfoDTO);
            return sleepHomeRateVO == null ? new SleepHomeRateVO() : sleepHomeRateVO;
        }else {
            List<Date> days = new ArrayList<>();
            if (TimeUnitEnums.WEEK.getCode().equals(sleepDetailInfoDTO.getType())) days = DateUtils.getWeekDatesLegacy(sleepDetailInfoDTO.getDailyValue());
            if (TimeUnitEnums.MONTH.getCode().equals(sleepDetailInfoDTO.getType())) days = DateUtils.getMonthDatesLegacy(sleepDetailInfoDTO.getDailyValue());
            SleepHomeRateVO sleepHomeRate = new SleepHomeRateVO();
            List<SleepHomeRateVO.LongSleepDate> longSleepDates = new ArrayList<>();
            int averages = 0;
            int num =0 ;
            for (Date date : days) {
                String str = "--";
                if (TimeUnitEnums.WEEK.getCode().equals(sleepDetailInfoDTO.getType()))
                    str = DateUtils.convertDateToMMdd(date);
                if (TimeUnitEnums.MONTH.getCode().equals(sleepDetailInfoDTO.getType()))
                    str = DateUtils.queryMonthday(date);
                SleepHomeRateVO.LongSleepDate longSleepDate = new SleepHomeRateVO.LongSleepDate();
                SleepHomeRateVO.LongSleepDate.LongSleepRateInfo longSleepRateInfo = new SleepHomeRateVO.LongSleepDate.LongSleepRateInfo();
                Date convertDate = DateUtils.dateTime(DateUtils.YYYY_MM_DD, DateUtils.dateTime(date));
                sleepDetailInfoDTO.setDailyValue(convertDate);
                SleepHomeRateVO sleepHomeRateVO = querySleepHeartRateResult(sleepDetailInfoDTO);
                if(sleepHomeRateVO != null){
                    averages += sleepHomeRateVO.getAverage();
                    int maxValue = sleepHomeRateVO.getMaxValue();
                    int minValue = sleepHomeRateVO.getMinValue();
                    longSleepRateInfo.setMaxValue(maxValue);
                    longSleepRateInfo.setMinValue(minValue);
                    longSleepDate.setLongSleepRateInfo(longSleepRateInfo);
                    num ++;
                }
                longSleepDate.setDailyValue(str);
                longSleepDates.add(longSleepDate);
            }
            sleepHomeRate.setAverage(num > 0 ? averages/num : 0);
            sleepHomeRate.setLongSleepDates(longSleepDates);
            return sleepHomeRate;
        }
    }

    public SleepHomeRateVO querySleepHeartRateResult(RingSleepDetailInfoDTO sleepDetailInfoDTO) {
        SleepHomeRateVO sleepHomeRateVO = null;
        RingSleepDetail ringSleepDetail = ringSleepDetailMapper.selectOneRingSleepDetail(Builder.of(RingSleepDetail::new).
                with(RingSleepDetail::setDeviceSn, sleepDetailInfoDTO.getDeviceSn()).
                with(RingSleepDetail::setDailyValue, sleepDetailInfoDTO.getDailyValue()).
                with(RingSleepDetail::setSleepType, SleepTypeEnums.LONG_SLEEP.getCode()).build());
        int average = 0;
        int minValue = 0;
        int maxValue = 0;
        RingHeartRateInfo heartRateInfo = ringHeartRateInfoMapper.selectOneRingHeartRateInfo(Builder.of(RingHeartRateInfo::new).
                with(RingHeartRateInfo::setDeviceSn, sleepDetailInfoDTO.getDeviceSn()).
                with(RingHeartRateInfo::setDailyValue, sleepDetailInfoDTO.getDailyValue()).build());
        List<SleepHomeRateVO.RingSleepHeartRate> list = new ArrayList<>();
        if(ringSleepDetail != null){
            if(heartRateInfo !=null){
                list = getSleepHeartRates(heartRateInfo.getHistoryDay(),heartRateInfo.getTimeInterval(),heartRateInfo.getHeartRateList().replace("null", "0").replace("255","0"),ringSleepDetail);
                int count = list.size();
                if(count > 0){
                    long totalSum = list.stream().mapToLong(rate -> rate.getValue()).sum();// 求和
                    average = (int)totalSum/count;
                }
                minValue = list.stream().mapToInt(rate -> rate.getValue()).min().orElse(0);
                maxValue = list.stream().mapToInt(rate -> rate.getValue()).max().orElse(0);
            }
            sleepHomeRateVO = new SleepHomeRateVO();
            sleepHomeRateVO.setAverage(average);
            sleepHomeRateVO.setMinValue(minValue);
            sleepHomeRateVO.setMaxValue(maxValue);
            sleepHomeRateVO.setHeartRateList(list);
        }
        return sleepHomeRateVO;
    }

    @Override
    public SleepHomeRateVO querySleepHrv(RingSleepDetailInfoDTO sleepDetailInfoDTO) {
        if(TimeUnitEnums.DAY.getCode().equals(sleepDetailInfoDTO.getType())){
            SleepHomeRateVO sleepHomeRateVO = querySleepHrvResult(sleepDetailInfoDTO);
            return sleepHomeRateVO == null ? new SleepHomeRateVO() : sleepHomeRateVO;
        }else {
            List<Date> days = new ArrayList<>();
            if (TimeUnitEnums.WEEK.getCode().equals(sleepDetailInfoDTO.getType())) days = DateUtils.getWeekDatesLegacy(sleepDetailInfoDTO.getDailyValue());
            if (TimeUnitEnums.MONTH.getCode().equals(sleepDetailInfoDTO.getType())) days = DateUtils.getMonthDatesLegacy(sleepDetailInfoDTO.getDailyValue());
            SleepHomeRateVO sleepHomeRate = new SleepHomeRateVO();
            List<SleepHomeRateVO.LongSleepDate> longSleepDates = new ArrayList<>();
            int averages = 0;
            int num =0 ;
            for (Date date : days) {
                String str = "--";
                if (TimeUnitEnums.WEEK.getCode().equals(sleepDetailInfoDTO.getType()))
                    str = DateUtils.convertDateToMMdd(date);
                if (TimeUnitEnums.MONTH.getCode().equals(sleepDetailInfoDTO.getType()))
                    str = DateUtils.queryMonthday(date);
                SleepHomeRateVO.LongSleepDate longSleepDate = new SleepHomeRateVO.LongSleepDate();
                SleepHomeRateVO.LongSleepDate.LongSleepRateInfo longSleepRateInfo = new SleepHomeRateVO.LongSleepDate.LongSleepRateInfo();
                Date convertDate = DateUtils.dateTime(DateUtils.YYYY_MM_DD, DateUtils.dateTime(date));
                sleepDetailInfoDTO.setDailyValue(convertDate);
                SleepHomeRateVO sleepHomeRateVO = querySleepHrvResult(sleepDetailInfoDTO);
                if(sleepHomeRateVO != null){
                    averages += sleepHomeRateVO.getAverage();
                    int maxValue = sleepHomeRateVO.getMaxValue();
                    int minValue = sleepHomeRateVO.getMinValue();
                    longSleepRateInfo.setMaxValue(maxValue);
                    longSleepRateInfo.setMinValue(minValue);
                    longSleepDate.setLongSleepRateInfo(longSleepRateInfo);
                    num ++;
                }
                longSleepDate.setDailyValue(str);
                longSleepDates.add(longSleepDate);
            }
            sleepHomeRate.setAverage(num > 0 ? averages/num : 0);
            sleepHomeRate.setLongSleepDates(longSleepDates);
            return sleepHomeRate;
        }
    }
    public SleepHomeRateVO querySleepHrvResult(RingSleepDetailInfoDTO sleepDetailInfoDTO) {
        SleepHomeRateVO sleepHomeRateVO = null;
        RingSleepDetail ringSleepDetail = ringSleepDetailMapper.selectOneRingSleepDetail(Builder.of(RingSleepDetail::new).
                with(RingSleepDetail::setDeviceSn, sleepDetailInfoDTO.getDeviceSn()).
                with(RingSleepDetail::setDailyValue, sleepDetailInfoDTO.getDailyValue()).
                with(RingSleepDetail::setSleepType, SleepTypeEnums.LONG_SLEEP.getCode()).build());
        int average = 0;
        int minValue = 0;
        int maxValue = 0;
        RingHrvInfo hrvInfo = ringHrvInfoMapper.selectOneRingHrvInfo(Builder.of(RingHrvInfo::new).
                with(RingHrvInfo::setDeviceSn, sleepDetailInfoDTO.getDeviceSn()).
                with(RingHrvInfo::setDailyValue, sleepDetailInfoDTO.getDailyValue()).build());
        List<SleepHomeRateVO.RingSleepHeartRate> list = new ArrayList<>();
        if(ringSleepDetail != null){
            if(hrvInfo !=null){
                String strValue = hrvInfo.getHrvList().replace("null", "0").replace("255","0");
                // 遍历所有心率数据点
                List<Integer> hrList = Arrays.stream(strValue.split(","))
                        .map(String::trim) // 去除每个元素前后的空格
                        .map(Integer::parseInt) // 转换为整数
                        .collect(Collectors.toList());
                int timeInterval = 24*60/hrList.size();
                list = getSleepHeartRates(hrvInfo.getDailyValue(),timeInterval,strValue,ringSleepDetail);
                int count = list.size();
                if(count > 0){
                    long totalSum = list.stream().mapToLong(rate -> rate.getValue()).sum();// 求和
                    average = (int)totalSum/count;
                }
                minValue = list.stream().mapToInt(rate -> rate.getValue()).min().orElse(0);
                maxValue = list.stream().mapToInt(rate -> rate.getValue()).max().orElse(0);
            }
            sleepHomeRateVO = new SleepHomeRateVO();
            sleepHomeRateVO.setAverage(average);
            sleepHomeRateVO.setMinValue(minValue);
            sleepHomeRateVO.setMaxValue(maxValue);
            sleepHomeRateVO.setStartDate(DateUtils.convertDateTimeToHHMM(ringSleepDetail.getStartDate()));
            sleepHomeRateVO.setEndDate(DateUtils.convertDateTimeToHHMM(ringSleepDetail.getEndDate()));
            sleepHomeRateVO.setHeartRateList(list);
        }

        return sleepHomeRateVO;
    }

    @Override
    public SleepHomeRateVO querySleepBloodOxygen(RingSleepDetailInfoDTO sleepDetailInfoDTO) {
        if(TimeUnitEnums.DAY.getCode().equals(sleepDetailInfoDTO.getType())){
            SleepHomeRateVO sleepHomeRateVO = querySleepBloodOxygenResult(sleepDetailInfoDTO);
            return sleepHomeRateVO == null ? new SleepHomeRateVO() : sleepHomeRateVO;
        }else {
            List<Date> days = new ArrayList<>();
            if (TimeUnitEnums.WEEK.getCode().equals(sleepDetailInfoDTO.getType())) days = DateUtils.getWeekDatesLegacy(sleepDetailInfoDTO.getDailyValue());
            if (TimeUnitEnums.MONTH.getCode().equals(sleepDetailInfoDTO.getType())) days = DateUtils.getMonthDatesLegacy(sleepDetailInfoDTO.getDailyValue());
            SleepHomeRateVO sleepHomeRate = new SleepHomeRateVO();
            List<SleepHomeRateVO.LongSleepDate> longSleepDates = new ArrayList<>();
            int averages = 0;
            int num =0 ;
            for (Date date : days) {
                String str = "--";
                if (TimeUnitEnums.WEEK.getCode().equals(sleepDetailInfoDTO.getType()))
                    str = DateUtils.convertDateToMMdd(date);
                if (TimeUnitEnums.MONTH.getCode().equals(sleepDetailInfoDTO.getType()))
                    str = DateUtils.queryMonthday(date);
                SleepHomeRateVO.LongSleepDate longSleepDate = new SleepHomeRateVO.LongSleepDate();
                SleepHomeRateVO.LongSleepDate.LongSleepRateInfo longSleepRateInfo = new SleepHomeRateVO.LongSleepDate.LongSleepRateInfo();
                Date convertDate = DateUtils.dateTime(DateUtils.YYYY_MM_DD, DateUtils.dateTime(date));
                sleepDetailInfoDTO.setDailyValue(convertDate);
                SleepHomeRateVO sleepHomeRateVO = querySleepBloodOxygenResult(sleepDetailInfoDTO);
                if(sleepHomeRateVO != null){
                    averages += sleepHomeRateVO.getAverage();
                    int maxValue = sleepHomeRateVO.getMaxValue();
                    int minValue = sleepHomeRateVO.getMinValue();
                    longSleepRateInfo.setMaxValue(maxValue);
                    longSleepRateInfo.setMinValue(minValue);
                    longSleepDate.setLongSleepRateInfo(longSleepRateInfo);
                    num ++;
                }
                longSleepDate.setDailyValue(str);
                longSleepDates.add(longSleepDate);
            }
            sleepHomeRate.setAverage(num > 0 ? averages/num : 0);
            sleepHomeRate.setLongSleepDates(longSleepDates);
            return sleepHomeRate;
        }
    }
    public SleepHomeRateVO querySleepBloodOxygenResult(RingSleepDetailInfoDTO sleepDetailInfoDTO) {
        SleepHomeRateVO sleepHomeRateVO = null;
        RingSleepDetail ringSleepDetail = ringSleepDetailMapper.selectOneRingSleepDetail(Builder.of(RingSleepDetail::new).
                with(RingSleepDetail::setDeviceSn, sleepDetailInfoDTO.getDeviceSn()).
                with(RingSleepDetail::setDailyValue, sleepDetailInfoDTO.getDailyValue()).
                with(RingSleepDetail::setSleepType, SleepTypeEnums.LONG_SLEEP.getCode()).build());
        int average = 0;
        int minValue = 0;
        int maxValue = 0;
        RingBloodOxygen ringBloodOxygen = ringBloodOxygenMapper.selectOneRingBloodOxygen(Builder.of(RingBloodOxygen::new).
                with(RingBloodOxygen::setDeviceSn, sleepDetailInfoDTO.getDeviceSn()).
                with(RingBloodOxygen::setDailyValue, sleepDetailInfoDTO.getDailyValue()).build());
        List<SleepHomeRateVO.RingSleepHeartRate> list = new ArrayList<>();
        if(ringSleepDetail != null ){
            if(ringBloodOxygen !=null){
                String strValue = ringBloodOxygen.getBloodList().replace("null", "0").replace("255","0");
                // 遍历所有心率数据点
                List<Integer> hrList = Arrays.stream(strValue.split(","))
                        .map(String::trim) // 去除每个元素前后的空格
                        .map(Integer::parseInt) // 转换为整数
                        .collect(Collectors.toList());
                int timeInterval = 24*60/hrList.size();
                list = getSleepHeartRates(ringBloodOxygen.getDailyValue(),timeInterval,strValue,ringSleepDetail);
                int count = list.size();
                if(count > 0){
                    long totalSum = list.stream().mapToLong(rate -> rate.getValue()).sum();// 求和
                    average = (int)(totalSum/count);
                }
                minValue = list.stream().mapToInt(rate -> rate.getValue()).min().orElse(0);
                maxValue = list.stream().mapToInt(rate -> rate.getValue()).max().orElse(0);
            }
            sleepHomeRateVO = new SleepHomeRateVO();
            sleepHomeRateVO.setAverage(average);
            sleepHomeRateVO.setMinValue(minValue);
            sleepHomeRateVO.setMaxValue(maxValue);
            sleepHomeRateVO.setStartDate(DateUtils.convertDateTimeToHHMM(ringSleepDetail.getStartDate()));
            sleepHomeRateVO.setEndDate(DateUtils.convertDateTimeToHHMM(ringSleepDetail.getEndDate()));
            sleepHomeRateVO.setHeartRateList(list);
        }
        return sleepHomeRateVO;
    }
    /**
     * @param dateValue 时间
     * @param timeInterval 间隔
     * @param strValue 逗号隔开的字符串
     * @param sleepDetail 睡眠详情对象
     * @return 时间戳与心率的映射列表，按时间排序
     */
    public static List<SleepHomeRateVO.RingSleepHeartRate> getSleepHeartRates(Date dateValue,int timeInterval, String strValue, RingSleepDetail sleepDetail) {
        // 转换时间单位：秒 -> 毫秒
        long intervalMs = timeInterval * 60L * 1000L;
        // 获取睡眠时间段的时间戳
        long sleepStartMs = sleepDetail.getStartDate().getTime();
        long sleepEndMs = sleepDetail.getEndDate().getTime();
        // 心率数据起始时间戳
        long hrStartMs = dateValue.getTime();
        // 存储结果的有序映射
        List<SleepHomeRateVO.RingSleepHeartRate> list = new ArrayList<>();
        // 遍历所有心率数据点
        List<Integer> hrList = Arrays.stream(strValue.split(","))
                .map(String::trim) // 去除每个元素前后的空格
                .map(Integer::parseInt) // 转换为整数
                .collect(Collectors.toList());
        for (int i = 0; i < hrList.size(); i++) {
            // 计算当前心率数据点对应的时间戳
            long currentTimeMs = hrStartMs + (long)i * intervalMs;
            // 检查该时间点是否在睡眠期间内
            if (currentTimeMs >= sleepStartMs && currentTimeMs <= sleepEndMs) {
                int hrValue = hrList.get(i);
                // 仅添加有效心率值(排除0值)
                if (hrValue > 0) {
                    SleepHomeRateVO.RingSleepHeartRate sleepHeartRate = new SleepHomeRateVO.RingSleepHeartRate();
                    sleepHeartRate.setKey(DateUtils.calculateTimeAfterMinutes(DateUtil.date(currentTimeMs),0));
                    sleepHeartRate.setValue(hrValue);
                    list.add(sleepHeartRate);
                }
            }
        }
        return list;
    }
    @Override
    public SleepActivityStatusVO querySleepActivityStatus(RingSleepDetailInfoDTO sleepDetailInfoDTO) {
        SleepActivityStatusVO sleepActivityStatusVO = new SleepActivityStatusVO();
        RingSleepDetail ringSleepDetail = ringSleepDetailMapper.selectOneRingSleepDetail(Builder.of(RingSleepDetail::new).
                with(RingSleepDetail::setDeviceSn, sleepDetailInfoDTO.getDeviceSn()).
                with(RingSleepDetail::setDailyValue, sleepDetailInfoDTO.getDailyValue()).
                with(RingSleepDetail::setSleepType, SleepTypeEnums.LONG_SLEEP.getCode()).build());
        RingEventInfo eventInfo = ringEventInfoMapper.selectOneRingEventInfo(Builder.of(RingEventInfo::new).with(RingEventInfo::setDeviceSn, sleepDetailInfoDTO.getDeviceSn()).with(RingEventInfo::setDailyValue, sleepDetailInfoDTO.getDailyValue()).build());
        List<RingSleepActivityStatusVO> activityStatusVOS = new ArrayList<>();
        if(ringSleepDetail != null){
            if(eventInfo !=null){
                activityStatusVOS = getSleepActivityStatus(eventInfo.getDailyValue(),30,eventInfo.getEventContent().replace("null", "0").replace("255","0"),ringSleepDetail);
            }
            sleepActivityStatusVO.setSleepStartDate(DateUtils.convertDateToMMdd(ringSleepDetail.getStartDate()));
            sleepActivityStatusVO.setSleepEndDate(DateUtils.convertDateToMMdd(ringSleepDetail.getEndDate()));
            sleepActivityStatusVO.setSleepTime(DateUtils.convertDateTimeToHHMM(ringSleepDetail.getStartDate()));
            sleepActivityStatusVO.setSoberTime(DateUtils.convertDateTimeToHHMM(ringSleepDetail.getEndDate()));
            sleepActivityStatusVO.setActivityStatusList(activityStatusVOS);
        }
        return sleepActivityStatusVO;
    }
    /**
     * @param dateValue 时间
     * @param timeInterval 间隔
     * @param strValue 逗号隔开的字符串
     * @param sleepDetail 睡眠详情对象
     * @return 时间戳与心率的映射列表，按时间排序
     */
    public static List<RingSleepActivityStatusVO> getSleepActivityStatus(Date dateValue,int timeInterval, String strValue, RingSleepDetail sleepDetail) {
        List<RingSleepActivityStatusVO> activityStatusVOList = new ArrayList<>();
        // 转换时间单位：秒 -> 毫秒
        long intervalMs = timeInterval * 60L * 1000L;
        // 获取睡眠时间段的时间戳
        long sleepStartMs = sleepDetail.getStartDate().getTime();
        long sleepEndMs = sleepDetail.getEndDate().getTime();
        long hrStartMs = dateValue.getTime();
        // 存储结果的有序映射
        List<RingSleepActivityStatusVO.RingSleepActivityStatus> list0 = new ArrayList<>();
        List<RingSleepActivityStatusVO.RingSleepActivityStatus> list1 = new ArrayList<>();
        List<RingSleepActivityStatusVO.RingSleepActivityStatus> list2 = new ArrayList<>();
        List<Integer> list = Arrays.stream(strValue.split(","))
                .map(String::trim) // 去除每个元素前后的空格
                .map(Integer::parseInt) // 转换为整数
                .collect(Collectors.toList());
        for (int i = 0; i < list.size(); i++) {
            // 计算当前心率数据点对应的时间戳
            long currentTimeMs = hrStartMs + (long)i * intervalMs;
            // 检查该时间点是否在睡眠期间内
            if (currentTimeMs >= sleepStartMs && currentTimeMs <= sleepEndMs) {
                int value = list.get(i);
                if (value < 10) {
                    RingSleepActivityStatusVO.RingSleepActivityStatus sleepHeartRate = new RingSleepActivityStatusVO.RingSleepActivityStatus();
                    sleepHeartRate.setKey(DateUtils.calculateTimeAfterMinutes(DateUtil.date(currentTimeMs),0));
                    sleepHeartRate.setValue(value);
                    list0.add(sleepHeartRate);
                }
                if (value >= 10 && value < 30) {
                    RingSleepActivityStatusVO.RingSleepActivityStatus activityStatus = new RingSleepActivityStatusVO.RingSleepActivityStatus();
                    activityStatus.setKey(DateUtils.calculateTimeAfterMinutes(DateUtil.date(currentTimeMs),0));
                    activityStatus.setValue(value);
                    list1.add(activityStatus);
                }
                if (value >= 50) {
                    RingSleepActivityStatusVO.RingSleepActivityStatus activityStatus = new RingSleepActivityStatusVO.RingSleepActivityStatus();
                    activityStatus.setKey(DateUtils.calculateTimeAfterMinutes(DateUtil.date(currentTimeMs),0));
                    activityStatus.setValue(value);
                    list2.add(activityStatus);
                }
            }
        }
        RingSleepActivityStatusVO sleepActivityStatusVO = new RingSleepActivityStatusVO();
        sleepActivityStatusVO.setActivityType("小幅活动");
        sleepActivityStatusVO.setActivityStatusList(list0);
        activityStatusVOList.add(sleepActivityStatusVO);
        sleepActivityStatusVO = new RingSleepActivityStatusVO();
        sleepActivityStatusVO.setActivityType("中幅活动");
        sleepActivityStatusVO.setActivityStatusList(list1);
        activityStatusVOList.add(sleepActivityStatusVO);
        sleepActivityStatusVO = new RingSleepActivityStatusVO();
        sleepActivityStatusVO.setActivityType("频繁活动");
        sleepActivityStatusVO.setActivityStatusList(list2);
        activityStatusVOList.add(sleepActivityStatusVO);
        return activityStatusVOList;
    }

    @Override
    public Map<String,Object> querySleepTrend(RingSleepDetailInfoDTO sleepDetailInfoDTO) {
        List<RingSleepDetail> sleepDetails = ringSleepDetailMapper.querySleepTrend(sleepDetailInfoDTO).stream().sorted(Comparator.comparing(RingSleepDetail::getId)).collect(Collectors.toList());
        long count = sleepDetails.stream().count();
        long totalSum = sleepDetails.stream()
                // 计算每个对象的totalTime + awakeTime
                .mapToLong(detail -> detail.getTotalTime() + detail.getAwakeTime())
                // 求和
                .sum();
        Map<String,Object> map = new HashMap<>();
        List<RingSleepTrendVO> sleepTrendVOS = new ArrayList<>();
        if(sleepDetails.size() > 0){
            sleepDetails.forEach(s ->{
                RingSleepTrendVO sleepTrendVO = new RingSleepTrendVO();
                sleepTrendVO.setDailyValue(s.getDailyValue());
                List<RingSleepTrendVO.RingTrend> list = new ArrayList<>();
                RingSleepTrendVO.RingTrend ringTrend = new RingSleepTrendVO.RingTrend();
                ringTrend.setValue(s.getAwakeTime());
                list.add(ringTrend);
                ringTrend = new RingSleepTrendVO.RingTrend();
                ringTrend.setValue(s.getRemTime());
                list.add(ringTrend);
                ringTrend = new RingSleepTrendVO.RingTrend();
                ringTrend.setValue(s.getLightTime());
                list.add(ringTrend);
                ringTrend = new RingSleepTrendVO.RingTrend();
                ringTrend.setValue(s.getDeepTime());
                list.add(ringTrend);
                sleepTrendVO.setTrendList(list);
                sleepTrendVOS.add(sleepTrendVO);
            });
            map.put("sleepDuration",DateUtils.convertMinutesToChinese((int)(totalSum/count)));
            map.put("chart",sleepTrendVOS);
        }
        return map;
    }

    @Override
    public List<SleepTrendWeekOrMonthVO> querySleepTrendWeekOrMonth(RingSleepDetailInfoDTO sleepDetailInfoDTO) {
        List<RingSleepDetail>  sleepDetailList = ringSleepDetailMapper.querySleepInfo(sleepDetailInfoDTO);
        List<SleepTrendWeekOrMonthVO> list = new ArrayList<>();
        List<Date> days = new ArrayList<>();
        if (TimeUnitEnums.WEEK.getCode().equals(sleepDetailInfoDTO.getType())) days = DateUtils.getWeekDatesLegacy(sleepDetailInfoDTO.getDailyValue());
        if (TimeUnitEnums.MONTH.getCode().equals(sleepDetailInfoDTO.getType())) days = DateUtils.getMonthDatesLegacy(sleepDetailInfoDTO.getDailyValue());
        for (Date date : days) {
            Date convertDate = DateUtils.dateTime(DateUtils.YYYY_MM_DD, DateUtils.dateTime(date));
            RingSleepDetail sleepDetail = sleepDetailList.stream().filter(ringSleepDetail -> ringSleepDetail.getDailyValue().getTime() == convertDate.getTime()).findFirst().orElse(null);
            SleepTrendWeekOrMonthVO sleepTrendWeekOrMonthVO = new SleepTrendWeekOrMonthVO();
            String str = "--";
            if (TimeUnitEnums.WEEK.getCode().equals(sleepDetailInfoDTO.getType())) str = DateUtils.convertDateToMMdd(date);
            if (TimeUnitEnums.MONTH.getCode().equals(sleepDetailInfoDTO.getType())) str = DateUtils.queryMonthday(date);
            sleepTrendWeekOrMonthVO.setDailyValue(str);
            if(sleepDetail != null){
                sleepTrendWeekOrMonthVO.setStartTime(DateUtils.convertDateTimeToHHMM(sleepDetail.getStartDate()));
                sleepTrendWeekOrMonthVO.setEndTime(DateUtils.convertDateTimeToHHMM(sleepDetail.getEndDate()));
            }
            list.add(sleepTrendWeekOrMonthVO);
        }
        return list;
    }
}
